#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>

#define  err_log(log) do{perror(log); }while(0)

#define  N 128

int main(int argc, const char *argv[])
{
	pid_t pid;
	pid = fork();
	
	//children parameter
	int sockfd_children;
	struct sockaddr_in broadcastaddr_children;
	char buf_children[N] = "nss send";
	int optval = 1;
	
	//parent parameter
	int sockfd_parent;
	char buf_parent[N];
	char validate_info[N] = "receive";
	struct sockaddr_in broadcastaddr_parent, srcaddr_parent;
	char *username, *pwd;

	switch(pid){
	//children process, used to send the message to the broadcast
	case 0:
		if((sockfd_children = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		{
		    err_log("send: fail to socket");
		}

		broadcastaddr_children.sin_family = AF_INET;
		broadcastaddr_children.sin_addr.s_addr = inet_addr("broadcast_ip");
		broadcastaddr_children.sin_port = htons(10000);

		if(setsockopt(sockfd_children, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int)) < 0)
		{
		    err_log("send: fail to setsockopt");
		}

		while(1)
		{
			sleep(3);
		    if(sendto(sockfd_children, buf_children, N, 0, (struct sockaddr *)&broadcastaddr_children, sizeof(broadcastaddr_children)) < 0)
		    {
		        err_log("send: fail to sendto");
		    }

		}
		break;
	//false create process
	case -1:
		err_log("send: fail to create the send process");
		break;
	//parent process, used to reveice the message from the server
	default:
		if((sockfd_parent = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		{
		    err_log("recv: fail to socket");
		}

		broadcastaddr_parent.sin_family = AF_INET;
		broadcastaddr_parent.sin_addr.s_addr = inet_addr("local_ip");
		broadcastaddr_parent.sin_port = htons(10000);

		if(bind(sockfd_parent, (struct sockaddr*)&broadcastaddr_parent, sizeof(broadcastaddr_parent)) < 0)
		{
		    err_log("recv: fail to bind");
		}

		socklen_t addrlen_parent = sizeof(struct sockaddr);

		while(1)
		{
		    if(recvfrom(sockfd_parent, buf_parent, N, 0, (struct sockaddr *)&srcaddr_parent, &addrlen_parent) < 0)
		    {
		        err_log("recv: fail to receive from");
		    }else{
		    	if (strstr(&buf_parent, &validate_info)){
                    strtok(buf_parent, " ");
                    username = strtok(NULL, " ");
                    pwd = strtok(NULL, " ");
                    printf("%s %s %s\n", inet_ntoa(srcaddr_parent.sin_addr), username, pwd);
		    		kill(pid, SIGTERM);
		    		break;
		    	}
		    }
		}
		break;
	}
    return 0;
}
